﻿using Kylin.Wiki.Core.Extensions.AutofacManager;
using Kylin.Wiki.Model.Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;

namespace Kylin.Wiki.Repository
{
    public class OnlyOfficeContext : DbContext, IDependency
    {
        private ILoggerFactory _LoggerFactory;
        public string DataBaseName = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        public OnlyOfficeContext()
               : base()
        {
        }


        public OnlyOfficeContext(DbContextOptions<OnlyOfficeContext> options)
         : base(options)
        {
        }
        public OnlyOfficeContext(string connction, ILoggerFactory loggerFactory)
            : base()
        {
            DataBaseName = connction;
            _LoggerFactory = loggerFactory;
        }


        public IUnitOfWork UnitOfWork { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.EnableSensitiveDataLogging(true);  //允许打印参数
            optionsBuilder.UseLoggerFactory(_LoggerFactory);
            //默认禁用实体跟踪
            optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); 
            base.OnConfiguring(optionsBuilder);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        { 
            try
            {
                //获取所有类库
                var compilationLibrary = DependencyContext
                    .Default
                    .CompileLibraries
                    .Where(x => !x.Serviceable && x.Type != "package" && x.Type == "project");
                foreach (var _compilation in compilationLibrary)
                {
                    //加载指定类
                    var list=AssemblyLoadContext.Default
                    .LoadFromAssemblyName(new AssemblyName(_compilation.Name))
                    .GetTypes()
                    .Where(x =>
                        x.GetTypeInfo().BaseType != null
                        && x.BaseType == (typeof(BaseEntity)))
                        .ToList();
                    list.ForEach(t =>
                     {
                         modelBuilder.Entity(t).ToTable("sys_" + t.Name);
                         if(t.Name== "User_Role")
                         { 
                             modelBuilder.Entity<User_Role>().HasKey(t => new { t.RoleID, t.UserID });
                         }
                         if(t.Name== "Role_Menu")
                         {
                             modelBuilder.Entity<Role_Menu>().HasKey(t => new { t.RoleID, t.MenuID });
                         } 
                     });
                }
                
                base.OnModelCreating(modelBuilder); 
            }
            catch (Exception ex)
            {
                 
            }
        }
         
        public override DbSet<TEntity> Set<TEntity>()
        {
            return base.Set<TEntity>();
        } 

        public override int SaveChanges()
        {
            try
            {
                return base.SaveChanges();
            }
            catch (Exception ex)//DbUpdateException 
            {
                throw (ex.InnerException as Exception ?? ex);
            }
        }

    }


}
